home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Dissolve.c
-
- Copyright 1990 by Thomas Knoll.
-
- Think C source file for Dissolve example.
- */
-
- #include <MacTypes.h>
- #include <MemoryMgr.h>
- #include <ResourceMgr.h>
- #include <Quickdraw.h>
- #include <Color.h>
- #include <DialogMgr.h>
- #include <OSUtil.h>
- #include <PackageMgr.h>
- #include <SysErr.h>
- #include <ToolboxUtil.h>
- #include <pascal.h>
- #include <SetUpA4.h>
-
- #include "FilterInterface.h"
-
- #define nil 0L
- #define Length(string) (*(unsigned char *)(string))
-
- typedef struct TParameters
- {
- short percent;
- } TParameters, *PParameters, **HParameters;
-
- short gResult;
- FilterRecordPtr gStuff;
-
- /*****************************************************************************/
-
- /* Calls the host's TestAbort function */
-
- Boolean TestAbort (void)
-
- {
- return CallPascalB (gStuff->abortProc);
- }
-
- /*****************************************************************************/
-
- /* Calls the host's UpdateProgress procedure */
-
- void UpdateProgress (done, total)
-
- long done;
- long total;
-
- {
- CallPascal (done, total, gStuff->progressProc);
- }
-
- /*****************************************************************************/
-
- /* Centers a dialog template 1/3 of the way down on the main screen. */
-
- void CenterDialog (dt)
-
- DialogTHndl dt;
-
- #define menuHeight 20
-
- {
- Rect r;
- short width;
- short height;
-
- width = screenBits.bounds.right;
- height = screenBits.bounds.bottom;
-
- r = (**dt).boundsRect;
- OffsetRect (&r, -r.left, -r.top);
- OffsetRect (&r, (width - r.right) / 2,
- (height - r.bottom - menuHeight) / 3 + menuHeight);
- (**dt).boundsRect = r;
- }
-
- #undef menuHeight
-
- /*****************************************************************************/
-
- /* Displays the about dialog box for the plug-in module. */
-
- void DoAbout (void)
-
- #define dialogID 16000
-
- {
- short item;
- DialogPtr dp;
- DialogTHndl dt;
-
- dt = (DialogTHndl) GetResource ('DLOG', dialogID);
- HNoPurge ((Handle) dt);
- CenterDialog (dt);
-
- dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
-
- ModalDialog (nil, &item);
-
- DisposDialog (dp);
- HPurge ((Handle) dt);
- }
-
- #undef dialogID
-
- /*****************************************************************************/
-
- /* UserItem to outline the OK button in a dialog box. */
-
- pascal void OutlineOK (dp, item)
-
- DialogPtr dp;
- short item;
-
- {
- Rect r;
- Handle h;
- short itemType;
-
- SetUpA4 ();
-
- item = OK;
-
- GetDItem (dp, item, &itemType, &h, &r);
-
- PenNormal ();
- PenSize (3, 3);
-
- InsetRect (&r, -4, -4);
- FrameRoundRect (&r, 16, 16);
-
- PenNormal ();
-
- RestoreA4 ();
- }
-
- /*****************************************************************************/
-
- /* Asks the user for the plug-in filter module's parameters. Note that
- the image size information is not yet defined at this point. Also, do
- not assume that the calling program will call this routine every time the
- filter is run (it may save the data held by the parameters handle in
- a macro file). */
-
- void DoParameters (void)
-
- #define dialogID 16001
- #define hookItem 3
- #define percentItem 4
-
- {
- Rect r;
- long x;
- short j;
- Str255 s;
- Handle h;
- short item;
- DialogPtr dp;
- short itemType;
- DialogTHndl dt;
- Handle percentText;
-
- if (!gStuff->parameters)
- {
- gStuff->parameters = NewHandle (sizeof (TParameters));
-
- if (!gStuff->parameters)
- {
- gResult = memFullErr;
- return;
- }
-
- ((PParameters) *gStuff->parameters)->percent = 50;
- }
-
- dt = (DialogTHndl) GetResource ('DLOG', dialogID);
- HNoPurge ((Handle) dt);
- CenterDialog (dt);
-
- dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
-
- RememberA4 ();
-
- GetDItem (dp, hookItem, &itemType, &h , &r);
- SetDItem (dp, hookItem, itemType, (Handle) &OutlineOK, &r);
-
- GetDItem (dp, percentItem, &itemType, &percentText, &r);
-
- NumToString (((PParameters) *gStuff->parameters)->percent, s);
- SetIText (percentText, s);
-
- do
- {
- SelIText (dp, percentItem, 0, 32767);
-
- ModalDialog (nil, &item);
-
- if (item == OK)
- {
- GetIText (percentText, s);
-
- StringToNum (s, &x);
-
- if (x < 1 || x > 99)
- item = 0;
-
- for (j = 1; j <= Length (s); j++)
- if (s[j] < '0' || s[j] > '9')
- item = 0;
-
- if (item == 0)
- SysBeep (1);
- }
- }
- while (item != OK && item != Cancel);
-
- DisposDialog (dp);
- HPurge ((Handle) dt);
-
- if (item == Cancel)
- {
- gResult = 1;
- return;
- }
-
- ((PParameters) *gStuff->parameters)->percent = x;
- }
-
- #undef dialogID
- #undef hookItem
- #undef percentItem
-
- /*****************************************************************************/
-
- /* Prepare to filter an image. If the plug-in filter needs a large amount
- of buffer memory, this routine should set the bufferSpace field to the
- number of bytes required. */
-
- void DoPrepare (void)
-
- {
- }
-
- /*****************************************************************************/
-
- /* Requests pointer to the first part of the image to be filtered. */
-
- void DoStart (void)
-
- {
- gStuff->inRect = gStuff->filterRect;
- gStuff->inRect.bottom = gStuff->inRect.top + 1;
-
- gStuff->inLoPlane = 0;
- gStuff->inHiPlane = gStuff->planes - 1;
-
- gStuff->outRect = gStuff->inRect;
-
- gStuff->outLoPlane = 0;
- gStuff->outHiPlane = gStuff->planes - 1;
- }
-
- /*****************************************************************************/
-
- /* Filters the area and requests the next area. */
-
- void DoContinue (void)
-
- {
- short rand;
- short count;
- short plane;
- short percent;
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char *srcPtr;
- unsigned char *dstPtr;
-
- if (TestAbort ())
- {
- gResult = 1;
- return;
- }
-
- UpdateProgress ((long) gStuff->inRect.top - gStuff->filterRect.top,
- (long) gStuff->filterRect.bottom - gStuff->filterRect.top);
-
- percent = ((PParameters) *gStuff->parameters)->percent;
-
- r = gStuff->background.red >> 8;
- g = gStuff->background.green >> 8;
- b = gStuff->background.blue >> 8;
-
- srcPtr = (unsigned char *) gStuff->inData;
- dstPtr = (unsigned char *) gStuff->outData;
-
- count = gStuff->filterRect.right - gStuff->filterRect.left;
-
- while (count--)
- {
-
- rand = Random ();
- rand = (rand < 0 ? -rand : rand);
-
- if (rand % 100 < percent)
- if (gStuff->planes == 3)
- {
- *(dstPtr++) = r;
- *(dstPtr++) = g;
- *(dstPtr++) = b;
- srcPtr += 3;
- }
- else
- {
- *(dstPtr++) = r;
- srcPtr++;
- }
- else
- for (plane = 0; plane < gStuff->planes; plane++)
- *(dstPtr++) = *(srcPtr++);
-
- }
-
- gStuff->inRect.top = gStuff->inRect.top + 1;
- gStuff->inRect.bottom = gStuff->inRect.bottom + 1;
-
- if (gStuff->inRect.top >= gStuff->filterRect.bottom)
- SetRect (&gStuff->inRect, 0, 0, 0, 0);
-
- gStuff->outRect = gStuff->inRect;
- }
-
- /*****************************************************************************/
-
- /* This routine will always be called if DoStart does not return an error
- (even if DoContinue returns an error or the user aborts the operation).
- This allows the module to perform any needed cleanup. None is required
- in this example. */
-
- void DoFinish (void)
-
- {
- }
-
- /*****************************************************************************/
-
- /* Main dispatching routine. Initializes and sets up the global variables,
- and performs the operation specified by the selector. */
-
- pascal void main (selector, stuff, data, result)
-
- short selector;
- FilterRecordPtr stuff;
- long *data;
- short *result;
-
- {
-
- /* Allow access to global variables */
-
- RememberA0 ();
- SetUpA4 ();
-
- /* Copy the current quickdraw globals into the plug-in local copy */
-
- asm
- {
- MOVE.L (A5),A0 ; Get address of real quickdraw globals
- SUB.L #126,A0 ; Move to start
- LEA randSeed,A1 ; Get address of local copy
- MOVE.W #64,D0 ; Globals are 65 words long
- @1 MOVE.W (A0)+,(A1)+ ; Copy a word
- DBF D0,@1 ; Move to next word
- }
-
- /* Perform the requested operation */
-
- gStuff = stuff;
- gResult = noErr;
-
- switch (selector)
- {
-
- case filterSelectorAbout:
- DoAbout ();
- break;
-
- case filterSelectorParameters:
- DoParameters ();
- break;
-
- case filterSelectorPrepare:
- DoPrepare ();
- break;
-
- case filterSelectorStart:
- DoStart ();
- break;
-
- case filterSelectorContinue:
- DoContinue ();
- break;
-
- case filterSelectorFinish:
- DoFinish ();
- break;
-
- default:
- gResult = filterBadParameters;
-
- }
-
- *result = gResult;
-
- /* Restore the application's A4 register */
-
- RestoreA4 ();
-
- }
-